

#include "stdafx.h"
#include "CombatState_Casting.h"
#include "Combat/EvtCombat.h"
#include "Event/EvtImp.h"
#include "Combat/CombatSysImp.h"
#include "Entity/EntityIf.h"
#include "Move/EvtMove.h"


enum
{
	ttl_Casted = 10000,
};


CombatState_Casting::CombatState_Casting(void)
{
}

CombatState_Casting::~CombatState_Casting()
{
}

void
CombatState_Casting::enter()
{
	if (!m_wpCombat->EffectUpdate_CastStart(m_nTTL))
	{
		LOG_ERROR("CombatState_Casting: Enter Failed!\n");

		m_wpCombat->setState(Combat::CBS_Ready);
	}

	m_bCastedOut = false;
}

void
CombatState_Casting::leave()
{
	if (m_bCastedOut)
	{
		if (!m_wpCombat->EffectUpdate_CastEnded())
		{
			LOG_ERROR("CombatState_Casting: Leave Failed, End!\n");
		}

		if (m_nTTL<=0)
		{
			LOG_ERROR("CombatState_Casting: Leave after casted out, time out without stopping from server!\n");
		}
	}
	else
	{
		if (!m_wpCombat->EffectUpdate_CastCancel())
		{
			LOG_ERROR("CombatState_Casting: Leave Failed! Cancel\n");
		}
	}
}


bool 
CombatState_Casting::update(int nElapse)
{
	//
	//	Spell casting is in progress
	//
	/*if (m_wpCombat->getModifierCastingSpeed()==1000 || m_wpCombat->getModifierCastingSpeed()<=0)
	{
		m_nTTL -= nElapse;
	}
	else
	{
		m_nTTL -= nElapse *  m_wpCombat->getModifierCastingSpeed() / 1000;
	}*/

	if (m_nTTL<=0)
	{
		if (m_bCastedOut)
		{
			//
			//	Time out after casting ending request is sending
			//
			m_wpCombat->setState(Combat::CBS_CoolDown);
		}
		else
		{
			if (m_wpCombat->isCalculator())
			{
				m_bCastedOut = m_wpCombat->EffectUpdate_CastEnding();
				if (!m_bCastedOut)
				{
					m_wpCombat->setState(Combat::CBS_CoolDown);
				}
			}
			else
			{
				//
				//	For a demonstrator, we assume the cast ending sending out successfully.
				m_bCastedOut = true;
			}
			m_nTTL = ttl_Casted;
		}
	}
	return true;
}

void 
CombatState_Casting::onEvent(IEvt& evt)
{
	if (evt.getID()==EVT_Move)
	{
		if (m_bCastedOut)
		{
			//
			//	Maybe need to send a cancel message to server later
			if (m_wpCombat->isCalculator())
			{
				m_wpCombat->sendMsg_CbtCancel();
			}
		}
		m_wpCombat->setState(Combat::CBS_CoolDown);
	}
	else if (evt.getID()==EVT_CastStart)
	{
		if (!m_wpCombat->isCalculator())
		{
			m_wpCombat->onEvent_Cast(evt);
			m_wpCombat->setState(Combat::CBS_Ready);
		}
		else
		{
			LOG_ERROR("Failed, calculator should not received cast start when casting!\n");
		}
	}
	else if (evt.getID()==EVT_CastEnd)
	{
		if (m_wpCombat->hasSequence(evt.getDataX()) )
		{
			if (evt.getDataY())
			{
				if (m_bCastedOut)
				{
					//
					//	Maybe need to send a cancel message to server later
					if (m_wpCombat->isCalculator())
					{
						m_wpCombat->sendMsg_CbtCancel();
					}
				}

				m_wpCombat->setState(Combat::CBS_CoolDown);
			}
			else
			{
				m_wpCombat->setState(Combat::CBS_CoolDown);
			}
		}
		else
		{
			LOG_ERROR("Failed to end casting by hook, invalid sequence!\n");
		}
	}
	else if (evt.getID()==EVT_CastResult)
	{
		m_wpCombat->onEvent_CastResult(evt);
	}
	else if (evt.getID()==EVT_CastPrep)
	{
		m_wpCombat->onEvent_CastPrep(evt);
	}
	else if (evt.getID()==EVT_TargetSelected)
	{
		m_wpCombat->onEvent_Target(evt);
	}
}


